package org.apogee.mil.client.main.pages.trainee.forms;

import java.util.ArrayList;
import java.util.List;

import org.apogee.mil.client.factories.ServerServiceFactory;
import org.apogee.mil.client.utils.Session;
import org.apogee.mil.client.utils.Template;
import org.apogee.mil.client.widgets.DialogHelper;
import org.apogee.mil.shared.Question;
import org.apogee.mil.shared.User;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.FormButtonBinding;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
import com.extjs.gxt.ui.client.widget.form.SimpleComboValue;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.extjs.gxt.ui.client.widget.tips.QuickTip;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class SelectionForm extends LayoutContainer {

	private FormData data;
	private int sessionId = -1;
	private ListStore<BaseModel> store = new ListStore<BaseModel>();
	private ListStore<BaseModel> volumeStore = new ListStore<BaseModel>();
	private ColumnModel cm;
	private Grid<BaseModel> grid;
	private User currentUser;
	private ComboBox<BaseModel> volumeBox;
	private int selectedAccess = 1;
	private int selectedVolume = 0;
	private String selectedTest = "";
	
	public SelectionForm() {
		this.currentUser = ServerServiceFactory.getUser(Session.getSessionId());
		this.sessionId = currentUser.getSessionId();
	}

	@SuppressWarnings("rawtypes")
	@Override
	protected void onRender(Element parent, int pos) {
		super.onRender(parent, pos);
		data = new FormData("100%");
		FormPanel form = new FormPanel();
		form.setHeading("Selection");  
		form.setFrame(true);
		form.setBorders(true);
		form.setSize(500, 400);
		form.setBodyBorder(true);
		form.setButtonAlign(HorizontalAlignment.CENTER);

		ServerServiceFactory.getTraineeService(sessionId).getAvailableTests(currentUser.getUserId(), new AsyncCallback<ArrayList<BaseModel>>() {

			@Override
			public void onSuccess(ArrayList<BaseModel> result) {
				store.removeAll();
				store.add(result);
			}

			@Override
			public void onFailure(Throwable caught) {
				MessageBox.alert("Error", "Unable to get Test List", null);

			}
		});

		
		GridCellRenderer<BaseModel> renderer = new GridCellRenderer<BaseModel>() {
			
			@Override
			public Object render(BaseModel model, String property, ColumnData config,
					int rowIndex, int colIndex, ListStore<BaseModel> store,
					Grid<BaseModel> grid) {
				
				String val = (String) (model.get(property) == null ? "No Tests..." : model.get(property));
				return "<span qtitle='" + cm.getColumnById(property).getHeader() + "' qtip='" + val  
			            + "' style='font-weight: bold;color: #5d8aa8'>" + val + "</span>";
			}
		};
		
		ArrayList<ColumnConfig> configs = new ArrayList<ColumnConfig>();
		
		volumeBox = new ComboBox<BaseModel>();
		volumeBox.setEmptyText("Select Test Volumes...");
		volumeBox.setAllowBlank(false);
		volumeBox.setFieldLabel("Volumes");
		volumeBox.setStore(volumeStore);
		volumeBox.setDisplayField("volumeFmt");
		volumeBox.setTemplate(Template.getVolumeTemplate());
		volumeBox.addSelectionChangedListener(new SelectionChangedListener<BaseModel>() {

			@Override
			public void selectionChanged(SelectionChangedEvent<BaseModel> se) {
				try{
					String selection = se.getSelectedItem().get("volume");
					selectedVolume = Integer.parseInt(selection);
				} catch (Exception ex) {
					selectedVolume = -1;
				} 			}
		});
		
		
		ColumnConfig column = new ColumnConfig();
		column.setId("cdc");
		column.setHeader("Available Tests");
		column.setWidth(100);
		column.setRowHeader(true);
		column.setRenderer(renderer);
		configs.add(column);
		
		cm = new ColumnModel(configs);
		
		HorizontalPanel hp = new HorizontalPanel();
		hp.setStyleAttribute("padding", "10px");
		hp.setWidth(400);
		hp.setBorders(false);
		hp.setHorizontalAlign(HorizontalAlignment.LEFT);
		
		grid = new Grid<BaseModel>(store, cm);
		grid.setBorders(true);
		grid.setColumnLines(true);
		grid.getAriaSupport().setLabelledBy(form.getHeader().getId()+"-label");
		grid.setSize(105, 200);
		grid.addListener(Events.CellClick, new Listener<GridEvent>(){

			@Override
			public void handleEvent(GridEvent be) {
				String test = be.getModel().get("cdc");
				float minScore = be.getModel().get("minScore") == null? 67.0f : Float.parseFloat(String.valueOf(be.getModel().get("minScore")));
				currentUser.setTestMinScore(minScore);
				getVolumes(test);
			}
			
		});
		hp.add(grid);
		
		final TextField<Integer> question = new TextField<Integer>();
		question.setWidth(100);

		Label lbl = new Label("Number of Questions:    ");
		lbl.setStyleAttribute("padding", "10px");
		
		HorizontalPanel hp2 = new HorizontalPanel();
		hp2.setStyleAttribute("padding", "10px");
		hp.setBorders(false);
		hp.setHorizontalAlign(HorizontalAlignment.LEFT);
        
		hp2.add(lbl);
		hp2.add(question);
		
		VerticalPanel vp = new VerticalPanel();
		vp.setBorders(false);
		vp.setHorizontalAlign(HorizontalAlignment.LEFT);
		vp.add(hp2);
		hp.add(vp);
		
		hp2 = new HorizontalPanel();
		hp2.setStyleAttribute("padding", "10px");
		hp.setBorders(false);
		hp.setHorizontalAlign(HorizontalAlignment.LEFT);
		
		lbl = new Label("Select Volume: ");
		lbl.setStyleAttribute("padding", "10px");
		
		hp2.add(lbl);
		hp2.add(volumeBox);
		
		vp.add(hp2);
		
		hp2 = new HorizontalPanel();
		hp2.setStyleAttribute("padding", "10px");
		hp.setBorders(false);
		hp.setHorizontalAlign(HorizontalAlignment.LEFT);
		
		lbl = new Label("Selected Test: ");
		lbl.setStyleAttribute("padding", "10px");
		
		
	    final SimpleComboBox<String> access = new SimpleComboBox<String>();
	    access.setEmptyText("Test Type...");
	    access.setAllowBlank(false);
	    access.add(getAccessLevels());
	    access.setFieldLabel("Test Type");
	    access.setWidth(200);
	    access.addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<String>>() {
			
			@Override
			public void selectionChanged(
					SelectionChangedEvent<SimpleComboValue<String>> se) {
				try{
					String selection = se.getSelectedItem().getValue();
					selection = selection.substring(0, 1).trim();
					selectedAccess = Integer.parseInt(selection);
				} catch (Exception ex) {
					selectedAccess = -1;
				} 
			}
		});
		
		
		hp2.add(lbl);
		hp2.add(access);
		
		vp.add(hp2);
		
	    Button b = new Button("Ok");
	    b.addSelectionListener(new SelectionListener<ButtonEvent>() {
			
			@Override
			public void componentSelected(ButtonEvent ce) {
				mask("Please Wait...");
				final int numQuestions = question.getValue() == null ? 0 : Integer.parseInt(String.valueOf(question.getValue()));
				final int volume = selectedVolume == -1 ? 0 : selectedVolume;
				final int review = selectedAccess == -1 ? 1 : selectedAccess;
				
				ServerServiceFactory.getTraineeService(sessionId).getQuestions(selectedTest, numQuestions, 
						volume, review, new AsyncCallback<List<Question>>() {
							
							@Override
							public void onSuccess(List<Question> result) {
								currentUser.setRedo(true);
								currentUser.setCurrentTest(selectedTest);
								DialogHelper dialog = new DialogHelper("Test", new QuestionForm(result));
								dialog.show();
								getParent().setVisible(false);
								
							}
							
							@Override
							public void onFailure(Throwable caught) {
								MessageBox.alert("Error", "Unable to get questions", null);
								
							}
						});
				
			}
		});
	    
	    form.addButton(b);  
	    form.setButtonAlign(HorizontalAlignment.CENTER);
	      
	    FormButtonBinding binding = new FormButtonBinding(form);  
	    binding.addButton(b);
		
		form.add(hp, data);
		
		add(form);
		new QuickTip(grid);
		layout();
	}
	
	private List<String> getAccessLevels() {
		ArrayList<String> bm = new ArrayList<String>();
		bm.add("1 - All Questions");
		bm.add("2 - Test Questions Only");
		bm.add("3 - Review Questions Only");
		return bm;
	}

	private void getVolumes(String test) {
		volumeBox.getStore().removeAll();
		selectedTest = test;
		ServerServiceFactory.getTraineeService(sessionId).getTestVolumes(test, new AsyncCallback<ArrayList<BaseModel>>() {

			@Override
			public void onSuccess(ArrayList<BaseModel> result) {
				
				volumeStore.add(result);
				volumeBox.setStore(volumeStore);
				volumeBox.repaint();

			}

			@Override
			public void onFailure(Throwable caught) {
				MessageBox.alert("Error", "Unable to retreive volumes", null);

			}
		});

	}

}
